package com.xiangban.xiangbanmall.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xiangban.xiangbanmall.dao.*;
import com.xiangban.xiangbanmall.exception.BizException;
import com.xiangban.xiangbanmall.fegin.PayFeign;
import com.xiangban.xiangbanmall.model.*;
import com.xiangban.xiangbanmall.model.dto.UserMember;
import com.xiangban.xiangbanmall.model.res.ApiResult;
import com.xiangban.xiangbanmall.model.res.ApiResultCode;
import com.xiangban.xiangbanmall.utils.CommonUtils;
import com.xiangban.xiangbanmall.utils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.xiangban.xiangbanmall.utils.CommonUtils.BizEmpty;
import static com.xiangban.xiangbanmall.utils.CommonUtils.getRandomNumber;
import static com.xiangban.xiangbanmall.utils.DateUtil.*;

/**
 * @Author Mr. MaYaYun
 * @Data 2021/11/1 16:38
 */
@Service
@Slf4j
public class UserMemberService {

    private static final long ONE_HUNDRED_YEAR_TIME = 3155673600L;//会员百年有效时间
    private static final long ONE_YEAR_TIME = 31536000L;//会员一年有效时间


    @Autowired
    private MemberMapper userMemberMapper;
    @Autowired
    private CommonUtils commonUtils;
    @Autowired
    private RechargeRecordMapper userRechargeRecordMapper;
    @Autowired
    private PageUtil pageUtil;
    @Autowired
    private PayRecordMapper userPayRecordMapper;
    @Autowired
    private PayFeign payFeign;
    @Value("${system.accessId}")
    private String accessId;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MemberRecommendMapper memberRecommendMapper;
    @Autowired
    private MemberGradeMapper memberGradeMapper;
    @Autowired
    private TicketMapper ticketMapper;
    @Autowired
    private WalletRecordMapper walletRecordMapper;


    @Transactional
    public Object openUserMember(UserMember userMember) {
        int userId = Integer.parseInt(commonUtils.getUserIdByToken());

        if (BizEmpty(userMember.getPayType())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        TUser tUser = userMapper.selectUserInfo(userId);

        //获取是否已经开通会员
        HashMap<String, Integer> map1 = new HashMap<>();
        map1.put("userId",userId);
        map1.put("memberGradeId",userMember.getMemberGradeId());
        TUserMemberGrade userMemberGrade = userMemberMapper.selectUserMemberInfoByUserId(map1);
        if (userMemberGrade == null || userMemberGrade.getExpirationTime() < new Date().getTime()){
            //#微信支付
            //生成流水号
            String wasteNumber = commonUtils.getWasteNumber();  //Z202111121442271636699347400001
            //生成支付订单信息
            TUserPayRecord tUserPayRecord = new TUserPayRecord();
            tUserPayRecord.setUid(userId);
            tUserPayRecord.setWasteNumber(wasteNumber);
            tUserPayRecord.setType(1);
            tUserPayRecord.setStatus(1);
            tUserPayRecord.setPrice(userMember.getPrice()*100);
            tUserPayRecord.setPayType(1);
            userPayRecordMapper.insertUserPayRecord(tUserPayRecord);
            //调起支付
            HashMap<String, String> map = new HashMap<>();
            map.put("accessId",accessId);//系统帐户
            map.put("payType",userMember.getPayType());//支付类型 ：JSAPI APP
            map.put("price",tUserPayRecord.getPrice().toString());//金额 单位分
            map.put("openId",tUser.getOpenId());//openid
            map.put("wasteNumber",wasteNumber);//流水号
            HashMap<String, String> stringHashMap = new HashMap<>();
            stringHashMap.put("memberGradeId",userMember.getMemberGradeId().toString());
            map.put("attach", JSON.toJSONString(stringHashMap));
            log.info("开始调起统一下单接口，参数："+JSON.toJSONString(map));
            ApiResult<Object> objectApiResult = payFeign.unifiedOrder(map);
            if (!objectApiResult.isSuccess()){
                throw new BizException(objectApiResult.getMessage());
            }
            return objectApiResult.getDataMap();
        }else {
            throw new BizException(ApiResultCode.USER_MEMBER_EXIST);
        }

    }


    /**
     * @param userMember 用户id、金额
     */
    public Object addUserMoney(UserMember userMember) {
        userMember.setUserId(Integer.parseInt(commonUtils.getUserIdByToken()));

        if (BizEmpty(userMember.getMoney())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        BigDecimal money = userMember.getMoney().multiply(new BigDecimal(100));
        //#微信支付
        //生成流水号
        String wasteNumber = commonUtils.getWasteNumber();  //Z202111121442271636699347400001
        //生成充值支付订单信息
        TUserPayRecord tUserPayRecord = new TUserPayRecord();
        tUserPayRecord.setUid(userMember.getUserId());
        tUserPayRecord.setWasteNumber(wasteNumber);
        tUserPayRecord.setType(2);
        tUserPayRecord.setStatus(1);
        tUserPayRecord.setPrice(money.intValue());
        tUserPayRecord.setPayType(1);
        userPayRecordMapper.insertUserPayRecord(tUserPayRecord);
        //获取openid
        TUser tUser = userMapper.selectUserInfo(userMember.getUserId());

        //调起支付
        HashMap<String, String> map = new HashMap<>();
        map.put("accessId",accessId);//系统帐户
        map.put("payType",userMember.getPayType());//支付类型 ：JSAPI APP
        map.put("price",money.intValue()+"");//金额 单位分
        map.put("openId",tUser.getOpenId());//openid
        map.put("wasteNumber",wasteNumber);//流水号
        ApiResult<Object> objectApiResult = payFeign.unifiedOrder(map);
        if (!objectApiResult.isSuccess()){
            throw new BizException(objectApiResult.getMessage());
        }
        return objectApiResult.getDataMap();
    }

    public void updateUserMoney(UserMember userMember) {
        userMember.setUserId(Integer.parseInt(commonUtils.getUserIdByToken()));
        if (BizEmpty(userMember.getMoney())){
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        TUserMember tUserMember = new TUserMember();
        tUserMember.setUserId(userMember.getUserId());
        tUserMember.setMoney(userMember.getMoney());
        if (userMember.getPaymentTypes() == 3){//余额
            userMemberMapper.minusUserMoney(tUserMember);
        }else if (userMember.getPaymentTypes() == 4){//积分
            userMemberMapper.minusUserIntegral(tUserMember);
        }


    }

    public PageInfo<TUserRechargeRecord> getRechargeRecord() {
//        if (BizEmpty(commonUtils.getUserIdByToken())){
//            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
//        }
        int userId = Integer.parseInt(commonUtils.getUserIdByToken());
        PageHelper.startPage(pageUtil.getPage().getPageNum(),pageUtil.getPage().getPageSize());
        List<TUserRechargeRecord> tUserRechargeRecords = userRechargeRecordMapper.selectRechargeRecordList(userId);
        return new PageInfo<>(tUserRechargeRecords);
    }

    @Transactional
    public void businessProcessing(String wasteNumber,String attach) {
        log.info("回调通知参数:"+wasteNumber+", "+attach);

        //获取会员等级
        Integer memberGradeId = Integer.parseInt(JSONObject.parseObject(attach).get("memberGradeId")+"");

        //获取订单信息
        TUserPayRecord tUserPayRecord = userPayRecordMapper.selectUserPayRecordByWasteNumber(wasteNumber);
        //#会员开通
        if (tUserPayRecord.getType() == 1){

            HashMap<String, Integer> map1 = new HashMap<>();
            map1.put("userId",tUserPayRecord.getUid());
            map1.put("memberGradeId",memberGradeId);
            TUserMemberGrade userMemberGrade = userMemberMapper.selectUserMemberInfoByUserId(map1);
            if (userMemberGrade == null) {

                TUserMember userMember = userMemberMapper.getUserMember(tUserPayRecord.getUid());
                //生成会员等级
                TUserMemberGrade tUserMemberGrade = new TUserMemberGrade();
                tUserMemberGrade.setMemberId(userMember.getId());
                tUserMemberGrade.setMemberGradeId(memberGradeId);
                if (memberGradeId == 3) {
                    tUserMemberGrade.setExpirationTime((new Date().getTime() / 1000) + ONE_YEAR_TIME);
                } else {
                    tUserMemberGrade.setExpirationTime((new Date().getTime() / 1000) + ONE_HUNDRED_YEAR_TIME);
                }
                memberGradeMapper.insertMemberGrade(tUserMemberGrade);


                //生成会员权益
                memberBenefits(memberGradeId, tUserPayRecord.getUid());
                //检查是否有推荐人
                TUserRecommend userRecommend = memberRecommendMapper.selectIsRecommend(tUserPayRecord.getUid());
                if (userRecommend != null) {
                    //推荐用户成为相伴医路会员，即享有10%的推荐佣金
                    Map<String, Object> memberGrade = memberGradeMapper.getMemberGrade(memberGradeId);

                    BigDecimal divide = new BigDecimal(tUserPayRecord.getPrice()).multiply(new BigDecimal(memberGrade.get("recommendRate") + "")).setScale(2, BigDecimal.ROUND_HALF_UP);
                    TUserMember tUserMember1 = new TUserMember();
                    tUserMember1.setUserId(tUserPayRecord.getUid());
                    tUserMember1.setMoney(divide);
                    userMemberMapper.addUserMoney(tUserMember1);

                    //推荐人钱包佣金记录
                    TUserWalletRecord tUserWalletRecord = new TUserWalletRecord();
                    tUserWalletRecord.setUserId(userRecommend.getUserIdRecommend());
                    tUserWalletRecord.setDescribe("推荐用户佣金");
                    tUserWalletRecord.setMoney(divide);
                    tUserWalletRecord.setType(1);
                    tUserWalletRecord.setPayType(1);
                    walletRecordMapper.insertUserWalletRecord(tUserWalletRecord);
                }
            }
        }//#会员充值
        else if (tUserPayRecord.getType() == 2){
            //增加充值金额
            TUserMember tUserMember = new TUserMember();
            tUserMember.setUserId(tUserPayRecord.getUid());
            tUserMember.setMoney(new BigDecimal(tUserPayRecord.getPrice()).divide(new BigDecimal(100)));
            userMemberMapper.addUserMoney(tUserMember);
            //充值记录
            TUserRechargeRecord tUserRechargeRecord = new TUserRechargeRecord();
            tUserRechargeRecord.setUserId(tUserMember.getUserId());
            tUserRechargeRecord.setMoney(tUserMember.getMoney());
            userRechargeRecordMapper.insertRechargeRecord(tUserRechargeRecord);
            //钱包记录
            TUserWalletRecord tUserWalletRecord = new TUserWalletRecord();
            tUserWalletRecord.setUserId(tUserPayRecord.getUid());
            tUserWalletRecord.setDescribe("用户充值");
            tUserWalletRecord.setMoney(new BigDecimal(tUserPayRecord.getPrice()).divide(new BigDecimal(100)));
            tUserWalletRecord.setType(1);
            tUserWalletRecord.setPayType(1);
            walletRecordMapper.insertUserWalletRecord(tUserWalletRecord);
        }
        //更改订单充值状态
        TUserPayRecord tUserPayRecord1 = new TUserPayRecord();
        tUserPayRecord1.setStatus(0);
        tUserPayRecord1.setWasteNumber(wasteNumber);
        userPayRecordMapper.updateUserPayRecordStatus(tUserPayRecord1);
    }


    public void registerMember(Integer memberGradeId, Integer uid){
        //生成会员信息
        TUserMember tUserMember = new TUserMember();
        tUserMember.setUserId(uid);
        tUserMember.setMoney(new BigDecimal(0));
        tUserMember.setIntegral(new BigDecimal(0));
        userMemberMapper.insertTUserMember(tUserMember);
        //生成会员等级
        TUserMemberGrade tUserMemberGrade = new TUserMemberGrade();
        tUserMemberGrade.setMemberId(tUserMember.getId());
        tUserMemberGrade.setMemberGradeId(memberGradeId);
        if (memberGradeId == 3){
            tUserMemberGrade.setExpirationTime((new Date().getTime()/1000) +ONE_YEAR_TIME);
        }else {
            tUserMemberGrade.setExpirationTime((new Date().getTime()/1000) +ONE_HUNDRED_YEAR_TIME);
        }
        memberGradeMapper.insertMemberGrade(tUserMemberGrade);
    }

    private void memberBenefits(Integer memberGradeId, Integer uid){

        //增加券次数
        int number = 1;//银卡送一次券，金卡送三次券，铂金卡无限量
        if (memberGradeId != 3){//铂金
            if (memberGradeId == 2){//金卡
                number = 3;
            }
            //生成会员权益
            for (int i = 0;i< number;i++){
                TUserTicket tUserTicket = new TUserTicket();
                tUserTicket.setUid(uid);
                tUserTicket.setTicketNo(Integer.parseInt(getRandomNumber(9)));
                tUserTicket.setStatus(0);
                ticketMapper.bindTicketWithUser(tUserTicket);
            }
        }
    }

    public Object getMemberGradeId(TUserMemberGrade userMemberGrade) {
        return memberGradeMapper.getMemberGrade(userMemberGrade.getMemberGradeId());
    }

    public void insertUserMoney(TUserMember userMember) {
        userMemberMapper.addUserMoney(userMember);
    }

    public void insertUserIntegral(TUserMember userMember) {
        userMemberMapper.addUserIntegral(userMember);
    }

    public Object getMemberGradeIdInfo() {
        int userId = Integer.parseInt(commonUtils.getUserIdByToken());
        List<HashMap<String, Object>> memberGradeIdInfo = userMemberMapper.getMemberGradeIdInfo(userId);
        if(memberGradeIdInfo.size() > 0){
            for (HashMap<String, Object> map : memberGradeIdInfo) {

                Object expiration_time = map.get("expiration_time");
                long longValue = Long.valueOf(String.valueOf(expiration_time)).longValue();
                String time = formatTime(longValue);
                map.put("expiration_time",time);

                Date create_time = (Date) map.get("create_time");
                String date = getNowDate(create_time);
                map.put("create_time",date);

            }
        }
        return memberGradeIdInfo;
    }

    public void withdraw(HashMap<String, String> map) {
        if (BizEmpty(map.get("price"))){//金额 单位分
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        if (BizEmpty(map.get("desc"))){//提现描述
            throw new BizException(ApiResultCode.PARAMETER_DEFICIENCY);
        }
        int userId = Integer.parseInt(commonUtils.getUserIdByToken());
        String wasteNumber = commonUtils.getWasteNumber();

        //提现流水记录
        TUserWalletRecord tUserWalletRecord = new TUserWalletRecord();
        tUserWalletRecord.setUserId(userId);
        tUserWalletRecord.setDescribe(map.get("desc"));
        tUserWalletRecord.setMoney(new BigDecimal(map.get("price")));
        tUserWalletRecord.setType(3);
        tUserWalletRecord.setPayType(1);
        tUserWalletRecord.setWasteNumber(wasteNumber);
        walletRecordMapper.insertUserWalletRecord(tUserWalletRecord);


        String price = new BigDecimal(map.get("price")).multiply(new BigDecimal(100)).setScale(0).toString();
        map.put("accessId",accessId);
        map.put("price",price);
        //获取openId
        TUser tUser = userMapper.selectUserInfo(userId);
        map.put("openId",tUser.getOpenId());
        map.put("wasteNumber",wasteNumber);
        payFeign.transfers(map);
    }
}
